﻿using Baseball.Infrastructure;
using Baseball.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Baseball.Repositories
{
    public class GameRepository
    {
        public async Task<List<Game>> GetGames(DateTime? Date = null)
        {
            // 기본값은 오늘
            if (Date == null)
                Date = DateTime.Today;

            List<Game> Games = new List<Game>(); // 반환할 Game 리스트
            HttpClient Client = new HttpClient();

            // URI를 빌드해 주고
            Uri SiteUri = new Uri(
                    ParseInformation.GameSite
                        .Replace("{year}", ((DateTime)Date).ToString("yyyy"))
                        .Replace("{month}", ((DateTime)Date).ToString("MM"))
                        .Replace("{day}", ((DateTime)Date).ToString("dd"))
            );

            // 사이트의 정보를 받아와서
            string RawData = await Client.GetStringAsync(SiteUri);

            // 경기 정보를 담고 있는 div마다 잘라 주고 파싱
            foreach (Match GameMatch in ParseInformation.GameContainer.Matches(RawData))
            {
                // 경기 정보를 담고 있는 string
                string GameInfo = GameMatch.Value;

                // 팀 이름 및 점수 파싱
                MatchCollection TeamNameMatches     = ParseInformation.GameTeam.Matches(GameInfo);
                MatchCollection TeamScoreMatches    = ParseInformation.GameTeamScore.Matches(GameInfo);

                // 경기 시작 시간 및 장소 파싱
                string GamePlaceTimeInfo = ParseInformation.GamePlaceTime.Match(GameInfo).Value;
                string StartTime = ParseInformation.Span.Match(GamePlaceTimeInfo).Value;
                string Stadium = GamePlaceTimeInfo.Split(' ')[0];

                // 경기 현황 파싱
                string Status = ParseInformation.GameStatus.Match(GameInfo).Value;

                // 이닝별 점수 파싱
                // 1번째 줄 : 구분이므로 pass
                // 2번째 줄 : 홈팀 이닝별 스코어
                // 3번째 줄 : 어웨이팀 이닝별 스코어
                string[] HomeTeamInningScore = new string[16];
                string[] AwayTeamInningScore = new string[16];

                // Row 3개를 받아와서
                MatchCollection InningScoreRowMatches = ParseInformation.GameTeamInningScoreTableRow.Matches(GameInfo);

                // 2번째 Row가 어웨이 팀 이닝별 스코어이므로
                int Index = 0; // MatchCollection은 IList 상속 X -> IndexOf X
                foreach (Match InningScoreDataMatch in ParseInformation.GameTeamInningScoreTableData.Matches(InningScoreRowMatches[1].Value))
                {
                    AwayTeamInningScore[Index] = InningScoreDataMatch.Value;
                    Index++;
                }

                // 3번째 Row가 어웨이 팀 이닝별 스코어이므로
                Index = 0;
                foreach (Match InningScoreDataMatch in ParseInformation.GameTeamInningScoreTableData.Matches(InningScoreRowMatches[2].Value))
                {
                    HomeTeamInningScore[Index] = InningScoreDataMatch.Value;
                    Index++;
                }

                // 투수 정보 파싱
                string TeamWinPitcherInfo = ParseInformation.GameTeamWinPitcherContainer.Match(GameInfo).Value;
                bool? IsGameFinished = !String.IsNullOrEmpty(TeamWinPitcherInfo); // 경기가 끝난지 안 끝난지 확인(무승부면 null을 담는다, 뒤에서 설정함)

                string WinPitcher = "정보 없음", LosePitcher = "정보 없음", SavePitcher = "정보 없음"; // 승, 패, 세 투수
                string HomeTeamFirstPitcher = "정보 없음", AwayTeamFirstPitcher = "정보 없음"; // 각 팀 선발투수

                // 경기가 끝났으면 (승/패/세 정보가 있으면)
                // 무승부일 경우에는 빈 Div라서 아무것도 Match되지 않아 오류 발생하므로 GameTeamWinPitcher Match 여부도 확인 필요
                if ((bool)IsGameFinished && ParseInformation.GameTeamWinPitcher.IsMatch(TeamWinPitcherInfo))
                {
                    MatchCollection PitcherMatches = ParseInformation.GameTeamWinPitcher.Matches(TeamWinPitcherInfo);

                    WinPitcher = PitcherMatches[0].Value;
                    LosePitcher = PitcherMatches[1].Value;

                    // 세이브 투수는 없을 수도 있으므로
                    try
                    {
                        SavePitcher = PitcherMatches[2].Value;
                    }
                    catch
                    {
                    }
                }
                // 경기가 아직 끝나지 않았으면 선발투수 정보가 표시됨
                else if (ParseInformation.GameTeamFirstPitcher.IsMatch(GameInfo))
                {
                    MatchCollection FirstPitcherInfo = ParseInformation.GameTeamFirstPitcher.Matches(GameInfo);

                    HomeTeamFirstPitcher = FirstPitcherInfo[1].Value;
                    AwayTeamFirstPitcher = FirstPitcherInfo[0].Value;
                }

                // 정보를 Games에 추가
                Games.Add(new Game
                {
                    HomeTeam = TeamNameMatches[1].Value,
                    AwayTeam = TeamNameMatches[0].Value,
                    HomeTeamScore = TeamScoreMatches[1].Value.Put0IfEmpty(),
                    AwayTeamScore = TeamScoreMatches[0].Value.Put0IfEmpty(),
                    HomeTeamInningScore = HomeTeamInningScore,
                    AwayTeamInningScore = AwayTeamInningScore,
                    Status = Status,
                    IsFinished = IsGameFinished,
                    StartTime = StartTime,
                    Stadium = Stadium,
                    HomeTeamFirstPitcher = HomeTeamFirstPitcher,
                    AwayTeamFirstPitcher = AwayTeamFirstPitcher,
                    WinPitcher = WinPitcher,
                    LosePitcher = LosePitcher,
                    SavePitcher = SavePitcher
                });
            }

            return Games;
        }
    }
}
